package com.leejxx.admin.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.leejxx.admin.dao.AdChannelDao;
import com.leejxx.admin.dao.AdSensitiveDao;
import com.leejxx.admin.service.WemediaNewsAutoScanService;
import com.leejxx.apis.article.IArticleClient;
import com.leejxx.apis.wemedia.IWemediaClient;
import com.leejxx.common.aliyun.GreenImageScan;
import com.leejxx.common.aliyun.GreenTextScan;
import com.leejxx.model.admin.pojos.AdChannel;
import com.leejxx.model.admin.pojos.AdSensitive;
import com.leejxx.model.article.dtos.ArticleDto;
import com.leejxx.model.common.dto.ResponseResult;
import com.leejxx.model.wemedia.pojos.WmNews;
import com.leejxx.model.wemedia.pojos.WmUser;
import com.leejxx.utils.common.SensitiveWordUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author LeeJx
 * @ClassName WemediaNewsAutoScanServiceImpl
 * @Description TODO
 * @date 2021/2/28 13:54
 * @Version 1.0
 */
@Service
@Transactional
@Slf4j
public class WemediaNewsAutoScanServiceImpl implements WemediaNewsAutoScanService {
    @Value("${file.oss.web-site}")
    private String webSite;

    @Autowired
    private IWemediaClient wemediaClient;

    /**
     * 自媒体文章审核
     *
     * @param id
     */
    @Override
    public void autoScanByMediaNewsId(Integer id) {

        if (id == null) {
            throw new RuntimeException("文章id不存在");
        }

        //1.查询自媒体文章
        WmNews wmNews = wemediaClient.findNewsById(id);
        if (wmNews == null) {
            throw new RuntimeException("文章不存在");
        }

        //2.文章状态为4，时间允许，保存数据
        if (wmNews.getStatus().equals(WmNews.Status.ADMIN_SUCCESS.getCode()) && wmNews.getPublishTime().getTime() < System.currentTimeMillis()) {
            //保存数据
            saveAppArticle(wmNews);
            return;
        }

        //3.文章状态为8，时间允许，保存数据
        if (wmNews.getStatus().equals(WmNews.Status.SUCCESS) && wmNews.getPublishTime().getTime() < System.currentTimeMillis()) {
            //保存数据
            saveAppArticle(wmNews);
            return;
        }

        if (wmNews.getStatus().equals(WmNews.Status.SUBMIT.getCode())) {

            //从文章内容中抽取出文本内容和图片内容，存入到一个map中
            Map<String, Object> contentAndImagesResult = handleTextAndImages(wmNews);

            //4.自管理敏感词审核
            boolean isSensitive = handleSensitive((String) contentAndImagesResult.get("content"), wmNews);
            if (!isSensitive) {
                return;
            }

            //5.文章文本和文章图片审核
            boolean isTextScan = handleTextScan((String) contentAndImagesResult.get("content"), wmNews);
            if (!isTextScan) {
                return;
            }

            boolean isImageScan = handleImageScan((List<String>) contentAndImagesResult.get("images"), wmNews);
            if (!isImageScan) {
                return;
            }

            //6.发布时间不允许，修改状态为8
            if (wmNews.getPublishTime().getTime() > System.currentTimeMillis()) {
                updateWmNews(wmNews, (short) 8, "审核通过，待发布");
                return;
            }

            //7.审核通过，保存app端相关文章
            saveAppArticle(wmNews);
        }


    }

    @Autowired
    private GreenImageScan greenImageScan;

    /**
     * 阿里云图片审核
     *
     * @param images
     * @param wmNews
     * @return
     */
    private boolean handleImageScan(List<String> images, WmNews wmNews) {
        if (images == null || images.size() == 0) {
            return true;
        }

        boolean flag = true;
        try {
            images = images.stream().distinct().collect(Collectors.toList());
            Map map = greenImageScan.greenImageScan(images);

            //审核失败
            if (map.get("suggestion").equals("block")) {
                flag = false;
                updateWmNews(wmNews, (short) 2, "文章图片中有违规元素");
            }
            //人工审核
            if (map.get("suggestion").equals("review")) {
                flag = false;
                updateWmNews(wmNews, (short) 3, "文章图片中有不确定元素");
            }
        } catch (Exception e) {
            e.printStackTrace();
            flag = false;
        }
        return flag;
    }

    @Autowired
    private GreenTextScan greenTextScan;

    /**
     * 阿里云文本审核
     *
     * @param content
     * @param wmNews
     * @return
     */
    private boolean handleTextScan(String content, WmNews wmNews) {
        boolean flag = true;
        try {
            Map map = greenTextScan.greenTextScan(content);
            //审核失败
            if (map.get("suggestion").equals("block")) {
                flag = false;
                updateWmNews(wmNews, (short) 2, "文章内容中有敏感词汇");
            }
            //人工审核
            if (map.get("suggestion").equals("review")) {
                flag = false;
                updateWmNews(wmNews, (short) 3, "文章内容中有不确定元素");
            }
        } catch (Exception e) {
            flag = false;
            e.printStackTrace();
        }

        return flag;
    }

    /**
     * 修改文章
     *
     * @param wmNews
     * @param status
     * @param msg
     */
    private void updateWmNews(WmNews wmNews, short status, String msg) {
        wmNews.setStatus(status);
        wmNews.setReason(msg);
        wemediaClient.updateWmNews(wmNews);
    }

    @Autowired
    private AdSensitiveDao adSensitiveDao;

    /**
     * 敏感词过滤
     *
     * @param content
     * @param wmNews
     * @return
     */
    private boolean handleSensitive(String content, WmNews wmNews) {

        boolean flag = true;

        //初始化敏感词库
        List<AdSensitive> adSensitives = adSensitiveDao.selectList(Wrappers.<AdSensitive>lambdaQuery().select(AdSensitive::getSensitives));
        List<String> allSensitives = adSensitives.stream().map(x -> x.getSensitives()).collect(Collectors.toList());

        SensitiveWordUtil.initMap(allSensitives);
        //匹配是否包含敏感词
        Map<String, Integer> map = SensitiveWordUtil.matchWords(content);
        if (map.size() > 0) {
            flag = false;
            updateWmNews(wmNews, (short) 2, "文章中包含了敏感词：" + map);
        }

        return flag;
    }

    /**
     * 从文章内容中抽取出文本内容和图片内容
     *
     * @param wmNews
     * @return
     */
    private Map<String, Object> handleTextAndImages(WmNews wmNews) {

        //文章内容  图片和文本
        String content = wmNews.getContent();
        //纯文本内容
        StringBuilder sb = new StringBuilder();
        //图片内容
        List<String> images = new ArrayList<>();

        List<Map> contentList = JSONArray.parseArray(content, Map.class);
        for (Map map : contentList) {
            //文本内容
            if (map.get("type").equals("text")) {
                sb.append(map.get("value"));
            }
            //图片
            if (map.get("type").equals("image")) {
                String imageUrl = (String) map.get("value");
                if (!imageUrl.startsWith(webSite)) {
                    imageUrl = webSite + imageUrl;
                }
                images.add(imageUrl);
            }
        }

        //文章封面图片
        if (StringUtils.isNotBlank(wmNews.getImages())) {
            String[] split = wmNews.getImages().split(",");
            for (String s : split) {
                if (!s.startsWith(webSite)) {
                    s = webSite + s;
                }
                images.add(s);
            }
        }

        Map<String, Object> result = new HashMap<>();
        result.put("content", sb.toString());
        result.put("images", images);
        return result;
    }

    /**
     * 保存app端相关文章
     *
     * @param wmNews
     */
    private void saveAppArticle(WmNews wmNews) {
        //保存文章
        ResponseResult responseResult = saveArticle(wmNews);
        if (!responseResult.getCode().equals(200)) {
            throw new RuntimeException("文章审核保存app文章失败");
        }
        //保存app端文章id
        Object data = responseResult.getData();
        wmNews.setArticleId((Long) data);
        updateWmNews(wmNews, (short) 9, "文章审核通过");
    }

    @Autowired
    private AdChannelDao adChannelDao;

    @Autowired
    private IArticleClient articleClient;

    /**
     * 保存文章
     *
     * @param wmNews
     * @return
     */
    private ResponseResult saveArticle(WmNews wmNews) {
        ArticleDto articleDto = new ArticleDto();
        if (wmNews.getArticleId() != null) {
            articleDto.setId(wmNews.getArticleId());
        }
        articleDto.setPublishTime(wmNews.getPublishTime());
        articleDto.setImages(wmNews.getImages());
        articleDto.setTitle(wmNews.getTitle());
        articleDto.setLayout(wmNews.getType());
        articleDto.setCreatedTime(new Date());
        //设置频道信息
        AdChannel adChannel = adChannelDao.selectById(wmNews.getChannelId());
        if (adChannel != null) {
            articleDto.setChannelName(adChannel.getName());
            articleDto.setChannelId(adChannel.getId());
        }
        //设置作者信息
        WmUser wmUser = wemediaClient.findWmUserById(wmNews.getUserId().longValue());
        articleDto.setAuthorName(wmUser.getName());
        articleDto.setContent(wmNews.getContent());
        return articleClient.saveArticle(articleDto);

    }
}
